package EP1.algoritmos;

import java.util.ArrayList;

public class Algoritmo3 implements Runnable {

    public static double sum;
    private int thread;
    private int n_threads;
    private int n;
    private static int n_pair;
    private ArrayList<Integer> primeList;
    private ArrayList<Twin> twinList;

    public Algoritmo3(ArrayList<Integer> primeList, int n, int n_threads,
	    int thread) {

	this.n = n;
	this.n_threads = n_threads;
	this.thread = thread;
	this.primeList = primeList;
    }

    public Algoritmo3(ArrayList<Integer> primeList, ArrayList<Twin> twinList, int n, int n_threads,
	    int thread) {

	this.n = n;
	this.n_threads = n_threads;
	this.thread = thread;
	this.primeList = primeList;
	this.twinList = twinList;
    }

    public static double calculaSoma(int cores, int n) {
	ArrayList<Thread> thread = new ArrayList<Thread>();
	ArrayList<Integer> primeList = new ArrayList<Integer>();
	ArrayList<Twin> twinList = new ArrayList<Twin>();

	sum = 0.0;
	n_pair = 0;

	if (cores == 1) {
	    Primes primes = new Primes(primeList, 1);

	    primes.makePrimesToTwin(n);

	    for (int i = 1; n_pair < n; i++) {
		long ei = primes.getPrimeList().get(i);
		long ej = primes.getPrimeList().get(i - 1);
		if (ei - ej == 2) {
		    double sum_p = (1.0 / ei) + (1.0 / ej);
		    sum += sum_p;
		    n_pair++;
		}
	    }
	    return sum;

	} else {
	    Primes p = new Primes(primeList, twinList , cores);
	    p.makePrimesToTwin(n + 1);

	    int n_threads = cores;
	    for (int i = 0; i < n_threads; i++) {
		thread.add(new Thread(
			new Algoritmo3(primeList, twinList, n, n_threads, i)));
	    }

	    for (Thread t : thread) {
		t.start();
	    }

	    for (Thread t : thread) {
		try {
		    t.join();
		} catch (InterruptedException e) {
		}
	    }
	    return sum;
	}
    }

    @Override
    public void run() {
	double parcial = 0.0;

	for (int i = this.thread; i < twinList.size(); i += n_threads) {
	    Long ei = new Long(twinList.get(i).ei);
	    Long ej = new Long(twinList.get(i).ej);

	    parcial += (1.0 / ej) + (1.0 / ei);

	}

	add(parcial);
    }

    public synchronized void add(double i) {
	sum += i;
    }

    public synchronized void add(int i) {
	sum += i;
    }
}
